package com.lz.chongqing;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * HutoolMain..
 *
 * @author Lizhong
 * @date 2021/8/19
 */
public class HutoolReuqest {

    static String commitUrl = "https://auth.cq.gov.cn:81/sso/forgot/user/step2";
    static String pcodeUrl = "https://auth.cq.gov.cn:81/web/checkcode?v=";
    static String pcodeIdentity = "http://pred.fateadm.com/api/capreg";
    static String Cookie = "Hm_lvt_de20de06da15ec1ee0893ff044edcf6e=1629369358; JSESSIONID=inspur72fda5002c33418aac362d8126d78b72; Hm_lpvt_de20de06da15ec1ee0893ff044edcf6e=1629381607";

    // http://www.fateadm.com/
    static String userId = "131276";
    static String secret = "";

    public static void main(String[] args) throws InterruptedException {
        fromFile();
        // identifyUsername("gbd9", "18536821123");
    }

    private static void fromFile() throws InterruptedException {
        ExcelReader reader = ExcelUtil.getReader(new File("D:\\explore\\wait03.xlsx"));
        List<List<Object>> read = reader.read(1);
        reader.close();

        List<String> users = read.stream().map(v -> String.valueOf(v.get(0) + "4049")).collect(Collectors.toList());
        List<ResultData> resultDataList = new ArrayList<>();
        int i = 13;
        System.out.println("start: " + i);
        for (; i < users.size(); i++) {
            System.out.println(i);
            ResultData work = work(users.get(i));
            while (work.code == -3 && work.msg.contains("验证码不正确")) {
                work = work(users.get(i));
                Thread.sleep(1000);
            }
            resultDataList.add(work);
            if (work.code == -2 || (work.code == -3 && work.getMsg().equals("500"))) {
                break;
            }
            Thread.sleep(200);

        }
        try {
            File destFile = new File("D:\\explore\\ret.xlsx");
            ExcelWriter writer = ExcelUtil.getWriter(destFile, "s1");
            writer.write(resultDataList, true);
            writer.close();

        } catch (Exception e) {
            System.out.println(resultDataList);
        }

        System.out.println("over: " + i);
    }

    private static ResultData work(String username) {
        ResultData ret = new ResultData();
        ret.username = username;

        String base64Img = null;
        try {

            base64Img = getCode(new Date().getTime());
        } catch (Exception e) {
            ret.code = -1;
            ret.msg = e.getMessage();
            return ret;
        }
        String pcode = null;
        try {
            pcode = identifyCode(base64Img);
        } catch (Exception e) {
            ret.code = -2;
            ret.msg = e.getMessage();
            return ret;
        }
        try {
            identifyUsername(pcode, username);
        } catch (Exception e) {
            ret.code = -3;

            ret.msg = e.getMessage();
            return ret;
        }
        return ret;
    }

    private static String identifyCode(String base64Img) {
        // user_id	是	string	用户id（用户中心页面的PD账号）
        // timestamp	是	string	请求时间戳（精确到秒）
        // sign	    是	string	签名串，签名串计算规则请看最后一栏
        // app_id	否	string	app id
        // asign	否	string	app签名串，签名串计算规则请看最后一栏
        // predict_type	是	string	识别类型
        // src_url	否	string	img_data的源网站地址，用于自动子类型分类用，以防识别率下降，单一类型为可选参数
        // up_type	否	string	有效值为”mt”，使用Multipart/form-data形式直接上传图片数据
        // img_data	是	string	识别数据，图片的数据

        long time = new Date().getTime();
        String sign = getSign(userId, time / 1000, secret);
        System.out.println(sign);
        Map<String, Object> pic = new HashMap<>();
        pic.put("src_url", "https://auth.cq.gov.cn:81");
        pic.put("user_id", userId);
        pic.put("sign", sign);
        pic.put("timestamp", time / 1000);
        pic.put("predict_type", "30400");
        pic.put("img_data", base64Img);
        String parma = HttpUtil.toParams(pic);
        HttpResponse resp = HttpUtil.createPost(pcodeIdentity)
                .header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
                .body(parma)
                .method(Method.POST)
                .execute();
        JSONObject jsonObject = JSON.parseObject(resp.body().toString());
        Object retCode = jsonObject.get("RetCode");
        if (!"0".equals(retCode)) {
            JSONObject errMsg = jsonObject.getJSONObject("ErrMsg");
            throw new RuntimeException(errMsg.toString());
        }
        String pcode = (String) JSON.parseObject((String) jsonObject.get("RspData")).get("result");
        return pcode;
    }

    private static void identifyUsername(String qcode, String username) {
        Map<String, Object> s = new HashMap<>();
        s.put("username", username);
        s.put("piccode", qcode);
        String s1 = HttpUtil.urlWithForm(commitUrl, s, StandardCharsets.UTF_8, false);
        HttpResponse form = HttpUtil.createPost(s1)
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36")
                .header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
                .header("Accept", "text/html, */*; q=0.01")
                .header("sec-ch-ua", "\"Chromium\";v=\"92\", \" Not A;Brand\";v=\"99\", \"Google Chrome\";v=\"92\"")
                .header("sec-ch-ua-mobile", "?0")
                .header("Cookie", Cookie)
                .body("username=" + username + "&" + "piccode=" + qcode)
                .method(Method.POST)
                .execute();
        // = "该账号不存在"; 12
        if (form.getStatus() != 200) {
            throw new RuntimeException("500");
        }
        int idx = form.toString().indexOf("errorMsg");

        if (idx > 0) {
            // System.out.println(form.toString());
            String substring = form.toString().substring(idx, idx + 23);
            throw new RuntimeException(substring);

        }
    }

    /**
     * 3YceX1nMgfh/pj16L4CB4HRK4pTN9k2Y
     * @param userId
     * @param timestamp
     * @param pwd
     * @return
     */
    public static String getSign(String userId, long timestamp, String pwd) {
        // sign  =     md5(pd_id + timestamp + md5( timestamp + pd_key))
        return MD5.create().digestHex(userId + timestamp + MD5.create().digestHex(timestamp + pwd));
    }

    private static String getCode(long timestamp) {
        // HttpResponse form = HttpUtil.createGet(pcodeUrl).header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36")
        //         .header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8").execute();
        // HttpUtil.downloadFileFromUrl(pcodeUrl,new File("C:\\Users\\li\\Desktop\\checkcode.jpg"));
//         BASE64Encoder encoder = new BASE64Encoder();
// String base64 = encoder.encodeBuffer(outputStream.toByteArray()).trim();
// base64 = base64.replaceAll("\n", "").replaceAll("\r", "");
// object.put("code", "data:image/jpg;base64," + base64);
// response.getWriter().write(object.toString());
        byte[] src = HttpUtil.createGet(pcodeUrl + timestamp, true).timeout(-1)
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36")
                .header("sec-ch-ua", "\"Chromium\";v=\"92\", \" Not A;Brand\";v=\"99\", \"Google Chrome\";v=\"92\"")
                .header("sec-ch-ua-mobile", "?0")
                .header("Cookie", Cookie)
                .execute()
                .bodyBytes();

        // byte[] source = HttpUtil.downloadBytes(pcodeUrl + timestamp);
        return Base64.encode(src);
    }


}
